/*
 * @Author: Clark
 * @Email: haixuanwoTxh@gmail.com
 * @Date: 2023-01-28 16:33:26
 * @LastEditors: Clark
 * @LastEditTime: 2023-01-28 16:48:17
 * @Description: file content
 */
#include "apue.h"
#include <pthread.h>

int quitflag;
sigset_t mask;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t waitlock = PTHREAD_COND_INITIALIZER;

void *thr_fn(void *arg)
{
    int err, signo;

    while (1)
    {
        err = sigwait(&mask, &signo);
        if (0 != err)
        {
            err_exit(err, "sigwait failed");
        }

        switch (signo)
        {
            case SIGINT:
            {
                printf("\ninterrupt\n");
                break;
            }
            case SIGQUIT:
            {
                pthread_mutex_lock(&lock);
                quitflag = 1;
                pthread_mutex_unlock(&lock);
                pthread_cond_signal(&waitlock);
                return 0;
            }
            default:
            {
                printf("unexpected signal %d\n", signo);
                break;
            }
        }
    }
}

int main(void)
{
    int err;
    sigset_t oldmask;
    pthread_t tid;

    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGQUIT);

    err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask);
    if (0 != err)
    {
        err_exit(err, "SIG_BLOCK error");
    }

    err = pthread_create(&tid, NULL, thr_fn, 0);
    if (0 != err)
    {
        err_exit(err, "can't create thread");
    }

    pthread_mutex_lock(&lock);
    while (0 == quitflag)
    {
        pthread_cond_wait(&waitlock, &lock);
    }
    pthread_mutex_unlock(&lock);

    //  SIGQUIT has been caught and is now blocked; do whatever
    quitflag = 0;

    // reset signal mask which unblocks SIGQUIT
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
    {
        err_sys("SIG_SETMASK error");
    }

    exit(0);
}
